package com.dkha.server.controllers;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import com.alibaba.fastjson.JSONObject;
import com.dkha.common.enums.ApiUrlEnum;
import com.dkha.common.exception.DkException;
import com.dkha.common.fileupload.MinioUtil;
import com.dkha.common.http.HttpUtil;
import com.dkha.common.modules.vo.ReturnVO;
import com.dkha.common.util.JsonUtil;
import com.dkha.common.util.UtilValidate;
import com.dkha.server.modules.entities.FaceInformation;
import com.dkha.server.services.ICompareService;
import com.dkha.server.services.IFileService;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.dkha.common.enums.ErrEnum;
import com.dkha.common.enums.SocketEnum;
import com.dkha.common.modules.vo.face.FaceResEntity;
import com.dkha.common.redis.RedisUtils;
import com.dkha.server.common.config.TimeTransform;
import com.dkha.common.util.UtilValidate;
//import com.dkha.task.comm.TimerData;
//import com.dkha.task.modual.mapper.SysUserTokenDao;
//import com.dkha.task.modual.vo.BayonetVO;
import com.dkha.common.modules.vo.ReturnVO;
import com.dkha.common.util.JsonUtil;
import com.dkha.common.modules.vo.CompareFaceList;
import com.google.gson.Gson;
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@ServerEndpoint("/webSocketServer")
@Slf4j
public class WebSocketContral {


    private Session session;

    private FaceController faceController1;

    private TimeTransform timeTransform;

    private Gson gson =new Gson();

    private static CopyOnWriteArraySet<WebSocketContral> webSocketSet=new CopyOnWriteArraySet<WebSocketContral>();
    public static Map<String, WebSocketContral> myMap=new ConcurrentHashMap();

    private RedisUtils redisUtils;
    //此处是解决无法注入的关键
    private static ApplicationContext applicationContext;
    //要注入的service或者dao
//    private SysUserTokenDao sysUserTokenDao;

    public static void setApplicationContext(ApplicationContext applicationContext) {
        WebSocketContral.applicationContext = applicationContext;
    }

    @OnOpen
    public void opOpen(Session session)
    {
        redisUtils =applicationContext.getBean(RedisUtils.class);
        this.session=session;
        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        System.out.println("session信息："+ session + " 时间："+formatter.format(new Date()));
        if(myMap.containsKey(session.getId()))
        {
            try {
                this.session.close();
            } catch (IOException e) {
            }
//            log.error("已经存在");
            return;
        }
//        sysUserTokenDao=applicationContext.getBean(SysUserTokenDao.class);
//		String time=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());
//		SysUserTokenEntity sysUserTokenEntity= null;//sysUserTokenDao.getByToken(token,time);
//		if(UtilValidate.isEmpty(sysUserTokenEntity))
//		{
//		    log.error("token过期");
//            sessionSendMsg(session,gson.toJson(new ReturnVO(ErrEnum.UNAUTHORIZED)));
//            try {
//                this.session.close();
//            } catch (Exception e) {
//            }
//            return;
//        }
//		//广播使用
//        redisUtils.set("token",token);
//        //对应使用
//        redisUtils.set(RedisKeys.getSessionIdKey(session.getId()),token);
//        TimerData.tokens.put(session.getId(),token);
        webSocketSet.add(this);
        myMap.put(session.getId(), this);
		log.info(session.getId()+"【websocket消息】有新的连接，总数：{},{}",webSocketSet.size(),myMap.size());

    }
    @OnClose
    public void onClose()
    {
//		log.info(this.session.getId()+"【websocket消息】连接断开，总数：{},{}",webSocketSet.size(),myMap.size());
//        if(TimerData.bayonetMap.containsKey(this.session.getId())) {
//            TimerData.bayonetMap.remove(this.session.getId());
//        }
        myMap.remove(this.session.getId());
        webSocketSet.remove(this);
       log.info("关闭成功{},{}",webSocketSet.size(),myMap.size());
    }
    @OnMessage
    public void onMessage(String message)
    {
        faceController1 =applicationContext.getBean(FaceController.class);
//        log.error("接收数据:{}",message);
//        if(UtilValidate.isEmpty(this.session) || this.session.isOpen()==false){return;}
        //System.out.println(message);
        if(UtilValidate.isNotEmpty(message))
        {
            log.info("【websocket消息】收到客户端消息：{}",message);
            long start = System.currentTimeMillis();
            SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd aHH:mm:ss:SSS");
            System.out.println("收到comparelist数据时间："+dateFormatGmt.format(new Date()));
//            timeTransform = applicationContext.getBean(TimeTransform.class);
//            System.out.println("收到comparelist数据时间："+ timeTransform.trans());

            ReturnVO returnVO=gson.fromJson(message,ReturnVO.class);
            //System.out.println(message);
            if(returnVO.getMessage().equals("okplus")){
                    // List<FaceResEntity> facelist =gson.fromJson(gson.toJson(returnVO.getData()),List<FaceResEntity>.class);
                    List<FaceInformation> faceInformations = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference<List<FaceInformation>>() {});
                    long end =System.currentTimeMillis();
                    System.out.println("接收数据耗时"+ (end - start)+ "ms");
                   faceController1.sendWebsocket2(faceInformations);

            }
            else if(returnVO.getMessage().equals("okpro")) {
                if (UtilValidate.isNotEmpty(returnVO.getData())) {
                    // List<FaceResEntity> facelist =gson.fromJson(gson.toJson(returnVO.getData()),List<FaceResEntity>.class);
                    List<FaceResEntity> onfacelist = JsonUtil.string2Obj(JsonUtil.obj2String(returnVO.getData()), new TypeReference<List<FaceResEntity>>() {});
                    faceController1.sendWebsocket1(onfacelist);
                }
            }

        }
	    log.info("【websocket消息】收到客户端消息：{}","发送完成");
    }


    /**
     * 给指定id用户推送信息
     * @param message
     */
    public void sendMessage(String id,String message)
    {
        for(WebSocketContral websocket:webSocketSet)
        {
            if(websocket.session.getId().equals(id))
            {
//                log.info("【websocket消息】给ID={}发送消息，message={}",id,message);
                sessionSendMsg(websocket.session,message);
                break;
            }

        }
    }
    /**
     * 群发消息调用
     * @param message
     */
    public void sendMessage(String message)
    {
        for(WebSocketContral websocket:webSocketSet)
        {
//			log.info("【websocket消息】广播消息，message={}",message);
            sessionSendMsg(websocket.session,message);
        }
    }

    /**
     * 发送消息
     * @param session
     * @param message
     */
    private void sessionSendMsg(Session session,String message)
    {
        try {
            session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("socket发送消息错误："+e.getMessage());
        }
    }


}
